<template>
  <div class="player" v-loading.lock="loading" element-loading-background="rgb(0, 0, 0)">
    <EduAliyunPlayer
      ref="player"
      :args="aplayer"
      :showProgress="progressSwitch"
      v-if="!loading"
      @play="onPlayerPlay"
      @pause="onPlayerPause"
      @ready="onPlayerReady"
      @ended="onPlayerEnded"
      @timeupdate="onPlayerTimeupdate"
      @requestFullScreen="requestFullScreen"
      @cancelFullScreen="cancelFullScreen"
    >
      <div class="video-image" v-if="!loading && sectionDataType == 2" slot="image">
        <edu-image :src="detailInfo.cover_url" fit="contain"></edu-image>
      </div>
    </EduAliyunPlayer>

    <!--  防挂机-人脸验证 -->
    <EduFaceVerify
      v-if="faceModalVisible"
      :visible.sync="faceModalVisible"
      scene_key="course_section"
      :scene_id="faceSceneId"
      :scene_type="faceSceneType"
      @cancel="onVerifySuccess"
    ></EduFaceVerify>

    <!--  防挂机-弹题 -->
    <prevent-question
      v-if="questionVisible"
      :course_id="detailInfo.id"
      :course_type="detailInfo.course_type"
      :visible.sync="questionVisible"
      @click="onVerifySuccess"
    ></prevent-question>

    <!--  防挂机-弹窗 -->
    <prevent-popup
      v-if="popupVisible"
      :datas="playerData.onhook"
      :visible.sync="popupVisible"
      @click="onVerifySuccess"
    ></prevent-popup>
  </div>
</template>
<script>
import EduFaceVerify from '@/components/EduFaceVerify'
import { mapState, mapGetters } from 'vuex'
import eventVue from '../sectiobWatchEventVue.js'
import EduAliyunPlayer from '@/components/EduAliyunPlayer' // 播放器
import preventQuestion from './preventQuestion'
import preventPopup from './preventPopup'
import throttle from '@/utils/throttle.js'
const defaultProps = {
  id: 'player-con', // 播放器外层容器的dom元素ID
  source: '', // 视频播放地址URL
  vid: '', // 媒体转码服务的媒体ID
  playauth: '', // 播放凭证
  width: '100%', // 播放器宽度
  height: '486px', // 播放器高度
  cover: '', // 播放器默认封面图片
  format: 'm3u8', // 播放地址格式
  autoplay: false, // 播放器是否自动播放
  encryptType: 0, // 设置是否播放阿里云视频加密（私有加密）视频
  previewDuration: 0, // 预览时长
  previewEndHtml: '#endPreviewTemplate', // 预览结束后显示在播放器中间的字符串。默认为空。
  previewBarHtml: '观看完整视频,请先购买课程', // 预览结束后显示在播放器左下角的字符串。默认为空。
  controlBarVisibility: 'always', // 控制面板的实现
  marquee: ['', { fontSize: '20px', color: '#FF920A' }, 'random'] // 跑马灯
}
export default {
  props: ['detailInfo'],
  components: {
    EduFaceVerify,
    EduAliyunPlayer,
    preventQuestion,
    preventPopup
  },
  data() {
    return {
      player: null,
      aplayer: defaultProps,
      continue: false, // 播放完成后是否继续播放下一首，需定义@next事件
      controls: false, // 是否显示默认播放控件
      initialTime: 0, // 指定视频初始播放位置
      current: 0, // 当前进度(s)
      duration: 0, // 总时长(s)
      paused: true, // 是否处于暂停状态
      seek: false, // 是否处于拖动状态
      isFullScreen: false, // 是否处于全屏
      loading: true, //是否处于读取状态
      initialLoading: true, // 首次加载

      currentDuration: 0, // 记录学习时长

      previewEnd: false, // 试看状态
      previewDuration: 0, // 视频试看时长

      faceModalVisible: false, // 人脸验证弹出
      faceVerifyStart: false, // 人脸验证开始
      faceVerifyEnd: true, // 人脸验证结束
      faceVerifyNumber: 0, // 还需要验证次数
      faceIntervalTime: 0, //见时间间隔
      faceNextVerifyTime: 0, // 下一次验证时间
      faceSceneType: 2, // 场景
      faceSceneId: 0, // 验证id
      faceShootStatus: false, // 续播状态
      copyright_content: '', // 版权信息

      playerData: {},
      questionVisible: false, // 弹题
      popupVisible: false // 弹窗
    }
  },
  computed: {
    ...mapState({
      getCurrentPlayItem: state => state.course.currentPlayItem // 课时数据
    }),
    ...mapGetters({
      progressSwitch: 'projectSetting/getGlobProgress'
    }),
    sectionDataType() {
      return this.getCurrentPlayItem.section_data.data_type || 1
    },
    // 用户信息
    accountInfo() {
      return this.$store.getters['user/accountInfo']
    }
  },
  methods: {
    /**
     * 播放器初始化完成即将播放时回调
     */
    onPlayerReady(player) {
      this.player = player
      const marqueeData = this.playerData.marquee

      // dom插入版权声明
      if (this.copyright_content) {
        let content = $(
          `<div class="aliyun-preview-component-copyright"><div class="notice-content"><span class="notice-text">${this.copyright_content}</span></div></div>`
        )
        $('#player-con').append(content)

        // 设置间隔
        let aliyunH5Html = $('#player-con .aliyun-preview-component-copyright')
        let noticeHtml = $('#player-con .aliyun-preview-component-copyright .notice-content')
        noticeHtml.on('animationiteration', () => {
          aliyunH5Html.css({
            opacity: 0
          })
          noticeHtml.css({
            animationPlayState: 'paused'
          })
          setTimeout(() => {
            aliyunH5Html.css({
              opacity: 1
            })
            noticeHtml.css({
              animationPlayState: 'running'
            })
          }, marqueeData.frequency * 1000)
        })
      }

      setTimeout(() => {
        this.duration = player.getDuration() || this.getCurrentPlayItem.section_data.duration
        this.isFullScreen = player.fullscreenService.getIsFullScreen()
        if (this.initialLoading) {
          this.handleInitialTime(this.duration)
          this.initialLoading = false
        }
      }, 600)
    },
    /**
     * 播放时回调
     */
    onPlayerPlay() {
      this.paused = false
    },
    /**
     * 暂停播放时回调
     */
    onPlayerPause() {
      this.paused = true
    },
    /**
     * 播放结束时回调
     */
    onPlayerEnded() {
      this.handleAddLearning()
      // 顺序模式不跳转
      if (!this.playerData.course_lock == 1) {
        if (this.continue) {
          if (this.detailInfo.onhook_type == 3) {
            this.handleModalConfirm()
            this.faceSceneType = 1
            this.faceSceneId = this.playerData.next_position.id
            this.faceShootStatus = true
          } else {
            this.nextPlayer()
          }
        } else {
          this.paused = true
          this.current = 0
        }
      }
    },
    // 播放下一个视频
    nextPlayer() {
      this.paused = true
      this.current = 0
      // this.aplayer.autoplay = true;
      this.$store.commit('course/setCurrentPlayItem', {
        ...this.getCurrentPlayItem,
        ...this.playerData.next_position
      })
      const player = this.$refs.player
      if (player) {
        player.dispose() //销毁
      }
      if (this.getCurrentPlayItem.section_data.stock != 'bokecc') {
        this.getPlayerFile()
      }
    },
    /**
     * 播放位置发生改变时回调
     * currentTime： 当前播放时间
     */
    onPlayerTimeupdate(player) {
      let currentTime = player.getCurrentTime()
      if (!this.seek && currentTime > 0) {
        this.current = Math.floor(currentTime)
      }
      throttle(() => {
        this.currentDuration++
        if (this.currentDuration % 10 == 0) {
          this.handleAddLearning()
        }
        this.onVerifyTimeupdate() // 人脸
        this.onPreviewDurationEnd(currentTime) // 处理试看
      }, 1000)
    },
    // 当视频进入和退出全屏时
    requestFullScreen() {
      this.isFullScreen = true
    },
    // 取消全屏事件
    cancelFullScreen() {
      this.isFullScreen = false
    },
    // 获取播放地址
    async getPlayerFile() {
      this.loading = true
      this.initialLoading = true
      let class_id = this.detailInfo.course_type === 4 ? this.detailInfo.id : 0
      this.$api.getCourseSectionFileurl(
        this.getCurrentPlayItem.course_id,
        this.getCurrentPlayItem.id,
        {
          class_id: class_id
        },
        res => {
          const { data } = res
          this.playerData = data

          if (data.url_type === 1) {
            let arr = data.fileurl_array.reduce((obj, cur) => {
              obj[cur.definition] = cur.play_url
              return obj
            }, {})
            this.aplayer.source = JSON.stringify(arr)
          } else if (data.url_type === 2) {
            this.aplayer.source = data.fileurl_string
          }
          // 音视频才能续播
          let sectionType = data.next_position?.section_data?.data_type
          let continuePlay = sectionType == 1 || sectionType == 2
          this.continue = !this.$util.isEmpty(data.next_position.position) && continuePlay
          if (this.detailInfo.onhook_type == 3) {
            this.faceSceneId = this.getCurrentPlayItem.id
          }
          // 当前播放定位
          this.$store.dispatch('course/setCurrentPlayPosition', {
            ...data.curr_position
          })

          // 解锁模式,播放时保存已播放的id
          if (data.course_lock == 1) {
            this.$store.commit('course/setPlaySectionLock', this.getCurrentPlayItem.id)
          }

          this.initialTime = this.getCurrentPlayItem.section_rate.current_time
          this.current = this.initialTime
          this.handleAuditionTime() // 计算试听时长
          setTimeout(() => {
            this.handleVerifyInit() // 人脸
          }, 200)
          const player = this.$refs.player
          player && player.dispose() //销毁
          player && player.createDemoPlayer() // 创建

          // 跑马灯
          let marqueeData = data.marquee
          if (!this.$util.isEmpty(marqueeData)) {
            // 跑马灯
            if (this.sectionDataType == 1) {
              let marqueeContent = ''
              let name = ''
              let phone = ''
              if (marqueeData.username == 1) name = this.accountInfo.nick_name || ''
              if (marqueeData.phone == 1) phone = this.accountInfo.phone || ''
              marqueeContent = name + phone
              if (marqueeContent) {
                this.aplayer.marquee = [
                  marqueeContent,
                  {
                    fontSize: `${marqueeData.font_size}px`,
                    color: this.$util.hexToRgba(marqueeData.font_color, marqueeData.font_opacity)
                  },
                  'top',
                  marqueeData.frequency
                ]
              }
            }

            // 版权
            this.copyright_content = marqueeData.copyright == 1 ? marqueeData.copyright_content : ''
          }
          this.loading = false
        }
      )
    },
    // 计算试听时长
    handleAuditionTime() {
      this.previewEnd = false
      let buy = this.getCurrentPlayItem.is_buy
      if (this.$util.isDef(buy) && buy == 0) {
        let audition = this.getCurrentPlayItem.audition || 0
        let duration = this.getCurrentPlayItem.section_data.duration || this.duration || 0
        this.previewDuration = Math.round(duration * (audition / 100))
        this.aplayer.previewDuration = this.previewDuration
      }
    },
    // 处理试看结束
    onPreviewDurationEnd(currentTime) {
      if (!this.previewEnd && this.previewDuration !== 0 && this.previewDuration < this.duration) {
        if (Math.floor(this.previewDuration) < currentTime) {
          this.previewEnd = true
          this.player.seek(this.previewDuration) // 跳转到某个时间点播放
          this.player.pause()
          if (this.isFullScreen) {
            this.player.fullscreenService.cancelFullScreen()
          }
        }
      }
    },
    // 断点续播
    handleInitialTime(duration) {
      let buy = this.getCurrentPlayItem.is_buy
      if (this.$util.isDef(buy) && buy == 0) return
      if (this.initialTime > duration - 5) {
        this.player.seek(0) // 跳转到某个时间点播放
      } else {
        this.player.seek(this.initialTime) // 跳转到某个时间点播放
      }
    },
    /* 验证 */
    handleVerifyInit() {
      this.popupVisible = false // 弹窗
      this.questionVisible = false // 弹题

      this.currentDuration = 0 // 当前播放时长

      this.faceSceneType = 2
      this.faceShootStatus = false
      this.faceVerifyEnd = false
      this.faceNextVerifyTime = 0

      // 课时是否购买
      if (this.$util.isDef(this.getCurrentPlayItem.is_buy) && this.getCurrentPlayItem.is_buy == 0) {
        return
      }

      // 是否是视频
      if (
        this.$util.isDef(this.getCurrentPlayItem.section_data.data_type) &&
        this.getCurrentPlayItem.section_data.data_type != 1
      ) {
        return
      }

      // 是否开启验证
      if (this.detailInfo.onhook_type == 0) return

      if (this.detailInfo.onhook_type == 1) {
        const alertData = this.playerData.onhook
        this.faceVerifyNumber = alertData.alert_max_number // 验证次数
        this.faceIntervalTime = alertData.alert_time_interval * 60 //时间间隔
      } else if (this.detailInfo.onhook_type == 2) {
        const answerData = this.playerData.onhook_exam
        this.faceVerifyNumber = answerData.answer_max_number // 验证次数
        this.faceIntervalTime = answerData.answer_time_interval * 60 //时间间隔
      } else if (this.detailInfo.onhook_type == 3) {
        const faceData = this.playerData.face_data
        this.faceVerifyNumber = faceData.need_verify_number // 验证次数
        this.faceIntervalTime = faceData.verify_timespan * 60 // 时间间隔
      }

      this.nextVerifyTime()
    },
    // 计算下一次验证时间
    nextVerifyTime() {
      if (this.faceVerifyNumber > 0) {
        let time = this.currentDuration + this.faceIntervalTime
        this.faceNextVerifyTime = time
      } else {
        this.faceVerifyEnd = true
      }
    },
    // 播放时验证
    onVerifyTimeupdate() {
      if (
        !this.faceVerifyEnd &&
        this.faceNextVerifyTime > 0 &&
        this.faceNextVerifyTime <= this.currentDuration
      ) {
        if (this.isFullScreen) {
          this.player.fullscreenService.cancelFullScreen()
          this.isFullScreen = false
        }

        setTimeout(() => {
          if (this.detailInfo.onhook_type == 1) {
            this.popupVisible = true
          } else if (this.detailInfo.onhook_type == 2) {
            this.questionVisible = true
          } else if (this.detailInfo.onhook_type == 3) {
            this.handleModalConfirm()
          }
        }, 50)

        this.$refs.player.pause()
      }
    },
    // 去验证人脸
    handleModalConfirm() {
      if (this.faceVerifyStart) return
      this.faceVerifyStart = true
      // 验证人脸
      this.$messageBox
        .confirm('请进行人脸验证', {
          type: 'none',
          center: true,
          confirmButtonText: '去验证'
        })
        .then(() => {
          this.faceModalVisible = true
        })
        .catch(() => {
          this.faceVerifyStart = false
        })
    },
    // 人脸验证成功
    onVerifySuccess() {
      // 续播
      if (this.faceShootStatus) {
        this.nextPlayer()
      } else {
        this.faceVerifyNumber-- // 还需要验证次数
        this.nextVerifyTime()
        this.player.play() // 视频播放
      }
      this.faceVerifyStart = false
    },
    // 添加学习记录
    handleAddLearning() {
      let buy = this.getCurrentPlayItem.is_buy
      if (this.$util.isDef(buy) && buy == 0) return
      if (this.current <= 0) return
      this.$api.createCourseRecord({
        course_id: this.getCurrentPlayItem.course_id,
        section_id: this.getCurrentPlayItem.id,
        current_time: this.current
      })
    },
    // 生成随机数
    random(m, n) {
      m = m || 1
      n = n || 100
      if (m >= n) {
        n = m + 100
      }
      let w = n - m
      let num = Math.random() * w + m
      return Math.round(num)
    }
  },
  mounted() {
    this.getPlayerFile()
    eventVue.$on('sendSectionBybus', () => {
      this.loading = true
      if (this.getCurrentPlayItem.section_data.stock != 'bokecc') {
        this.getPlayerFile()
      }
    })
    // 点击右侧目录时暂停播放
    eventVue.$on('faceEntranceBybus', () => {
      const player = this.$refs.player
      player && player.pause()
    })
  },
  beforeDestroy() {
    const player = this.$refs.player
    player && player.dispose()
  }
}
</script>
<style lang="scss" scoped>
.player {
  color: #fff;
  width: 100%;
  height: 100%;
  overflow: hidden;
  position: relative;
  background-color: #000;
  /* 隐藏video 所有控件 */
  ::v-deep video::-webkit-media-controls {
    display: none !important;
  }
  ::v-deep video::-webkit-media-controls-enclosure {
    display: none !important;
  }
  ::v-deep .prism-player {
    .prism-controlbar .prism-controlbar-bg {
      background: rgba(0, 0, 0, 0.3);
    }
    .prism-cc-btn,
    .prism-setting-btn {
      //字幕和设置隐藏
      display: none;
    }
    .prism-time-display {
      color: #fff;
      font-size: 14px;
    }
    .prism-liveshift-progress .prism-progress-loaded,
    .prism-progress .prism-progress-loaded {
      background: rgba(255, 255, 255, 0.8);
    }
    .prism-liveshift-progress .prism-progress-played,
    .prism-progress .prism-progress-played {
      @include edu-color-primary(background-color);
    }
    .prism-liveshift-progress,
    .prism-progress {
      background: rgba(255, 255, 255, 0.3);
    }
    .prism-liveshift-progress .prism-progress-cursor,
    .prism-progress .prism-progress-cursor {
      top: -7px;
      background: #fff;
      @include edu-color-primary(border-color);
      img {
        display: none;
      }
    }
    .volume-icon {
      margin-right: 6px;
      line-height: 28px;
      text-align: center;
      background: none;
      font-family: 'eduline' !important;
      font-style: normal;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      &:before {
        content: '\e60e';
        font-size: 20px;
        color: #fff;
      }
      .short-horizontal,
      .long-horizontal {
        display: none;
      }
    }
    .prism-fullscreen-btn {
      background: none;
      font-family: 'eduline' !important;
      font-style: normal;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      &:before {
        content: '\edd0';
        font-size: 20px;
        color: #fff;
      }
      &:hover {
        animation: none;
      }
    }
    .prism-volume-control .volume-range {
      background: #ffffff;
    }
    .prism-volume-control .volume-cursor:hover,
    .prism-volume-control .volume-value {
      @include edu-color-primary(background-color);
    }
    .rate-list li.current,
    .quality-list li.current {
      @include edu-color-auxiliary;
    }
  }
  .video-image {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    .el-image {
      width: 100%;
      height: 100%;
    }
  }
}
</style>
<style>
.aliyun-preview-component-copyright {
  position: absolute;
  top: 10px;
  left: 10px;
  right: 10px;
  z-index: 999;
  padding: 5px 0;
  background: rgba(0, 0, 0, 0.2);
  overflow: hidden;
  display: flex;
}

.aliyun-preview-component-copyright .notice-content {
  animation: aliyun-loop-animation 10s linear infinite both;
  text-align: right;
  padding-left: 100%;
  display: flex;
  flex-wrap: nowrap;
  box-sizing: border-box;
}

.aliyun-preview-component-copyright .notice-text {
  font-size: 13px;
  font-weight: 400;
  color: #ffffff;
  line-height: 18px;
  word-break: keep-all;
  white-space: nowrap;
}

@keyframes aliyun-loop-animation {
  0% {
    transform: translate3d(0, 0, 0);
  }

  100% {
    transform: translate3d(-100%, 0, 0);
  }
}
</style>
